 
import { ABaseDecision } from "GameLoop/DecisionMaking/BaseDecision";
import { MainStrategy } from "GameLoop/WorldState/EntityManager/CreateStrategy/MainStrategy";
import { getRoleConfig } from "utils/constants/bodyconstant";
import { priority } from "utils/constants/definetypes";
import { structurePriority } from "utils/constants/priorityconstant";
import { BodyEfficiency } from "utils/creep/bodyEfficiency";
import { Roles } from "utils/creep/setups";
import { PositionHelper } from "utils/position/PositionHelper";
import { UtilsHelper } from "utils/position/UtilsHelper";
import { TaskHelper } from "utils/task/TaskHelper";
import { generateUniqueId } from "utils/utils";

/**
 * 建设任务决策
 */
export class BuildTaskDecision< T extends "creep"="creep"> extends ABaseDecision<T>
{
   
    public isExpired(event: NormalEvent, region: string): boolean 
    {
        const room = Game.rooms[event.region] as Required<Room>;
        if(!room || !room.controller.my)
        {
            Game.rooms[event.room].memory={} as any;
            return false;
        }
        const curbuildTask = room.getTaskByType("creep",(e:ITaskDeclare["creep"])=>e.data.type == "build" && e.data.room == event.room)[0];
        if(curbuildTask)
        {
            return false;
        }
        const workroom = Game.rooms[event.room]
        if(!workroom || (workroom.getType() == 6 && room.controller.level<7))
        {
            return false;
        }
        return true;

    }
    public makeTask(event: NormalEvent, region: string): IDecisionCode<T>|false
    {
       
        const room = Game.rooms[event.region] as Required<Room>;
        const workroom = Game.rooms[event.room] as Required<Room>;
     
        // 一半的收入用来建设
        if(!room.memory.stats)
        {
            global.Log.Info(`统计信息未初始化 ${JSON.stringify(room.memory.stats)}`);
            return false;
        }
        if(!workroom || workroom.memory.state)
        {
            return false;
        }
       
         
        let sites:Required<ObjectRef>[];
        let toolprogress = 0;
        if(event.region == event.room)
        {
            const spawnentity = room.getEntity("SpawnEntity");
            sites = _.sortBy( workroom.find(FIND_CONSTRUCTION_SITES),e=>
            {
                const val = structurePriority[e.structureType]?structurePriority[e.structureType]:100;
                toolprogress+=e.progressTotal-e.progress;
                const distance = e.pos.distance(spawnentity.BasePosition);
                return val+distance*0.001;
            }).map(e=>_.assign(e.pos,{id:e.id} ) as Required<ObjectRef>);
        }
        else
        {
            
            sites = _.sortBy( workroom.find(FIND_CONSTRUCTION_SITES),e=>
            {
                const val = structurePriority[e.structureType]?structurePriority[e.structureType]:100;
                toolprogress+=e.progressTotal-e.progress;
                return val
            }).map(e=>_.assign(e.pos,{id:e.id} ) as Required<ObjectRef>);
        }
        if(sites.length==0)
        {
             
            return false;
        }
        const body = getRoleConfig("worker",room.controller.level);
        let  maxcreeps=1;
        if(toolprogress>100)
        {
           maxcreeps =  BodyEfficiency.calCreepCountByProgress(toolprogress,body.body,"build");
            if(workroom.getType()==1||workroom.getType() ==6)
            {
                const useable={
                    body:room.memory.stats.governable.body*0.8,
                    energy:room.memory.stats.governable.energy*0.8
                } ;
                
                maxcreeps=  Math.min( BodyEfficiency.getMaxCreepAmount(useable,room.controller.level,"worker","build"),maxcreeps)
                // const min_limit = BodyEfficiency.getCreepCount("worker",room.controller?.level,WORK,10) ;
                maxcreeps = Math.max(maxcreeps,3);
                let upgrader = BodyEfficiency.getCreepCount("worker",room.controller?.level as number,WORK,10);
                maxcreeps = Math.max(maxcreeps,upgrader);
            }
            else  
            {
                let upgrader = BodyEfficiency.getCreepCount("worker",room.controller?.level as number,WORK,6);
                maxcreeps = Math.max(1,upgrader);
            }
        }
        else 
        {
            maxcreeps=1;
        }
        
        {
            const buildTask:ICreepTaskData<"build"> = 
            {
                type:"build",
                arg:{
                    Objects:sites
                },
                creeps:[],
                body:{},
                room:event.room,
                cost:TaskHelper.getTaskPathCost(event.region,event.room),
                income:-1,
                required:[
                    [['worker'],  Math.min( maxcreeps,15),Math.min( maxcreeps,15)]
                ]
            }
            // 根据数量。计算运输工数量
            const code:IDecisionCode<T>={
                region:event.region,
                isunique:false,
                task:[{
                    id:generateUniqueId(),
                    priority:priority.C,
                    ttl:5000,
                    type:"creep",
                    data:buildTask,
                    shard: Math.min( maxcreeps,15),
                }],
            }
            return code
        }
    }
    
}